// NOTA 
/*
Por errores en el laboratorio
charPointer. buscar "para laboratorio", conflictos de char
recv(socket_fd, NOM_JUG_1, sizeof(NOM_JUG_1), 0);  320 ver (void*)
*/
 

#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <stdlib.h>
#include <sys/types.h>  // socket
#include <sys/socket.h> // socket, inet_addr
#include <netinet/in.h> // inet_addr
#include <arpa/inet.h>  // inet_addr
#include <unistd.h>     // close
#include <fstream>
#include <pthread.h>
#include <signal.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <queue>
#include <time.h>  // para clock
#include <sys/time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>

#include "headers/sdl.h"
#include "headers/socket.h"
#include "headers/funciones_generales.h"
#include "headers/pthread.h"

#define TAMBUF 26
#define OBJETOS 30   // cantidad de personajes incluyendo barriles y fuego
#define SHMKEY 53
#define PATH_MONITOR "../../MonitorClient/Debug/MonitorClient"



// PPP: etiqueta, se debe comentar las lineas que contengan esta etiqueta. Solo se usan para que el SP se pueda conectar al cliente. 
/// El cliente queda a la escucha


using namespace std;

// ignara todas las seniales
void ignore_signals(void);

// MONITOR
void ejecutar_monitor(void);
void reEjecutar_monitor(void);

void * th_f_torneo(void *);
void * th_f_capturar_teclas(void *);
void * th_f_carga_movimientos(void *);
void * th_f_mostrar_pantalla(void*);
void * th_f_monitorizar_monitor(void *);

pthread_mutex_t mutex_carga_movimientos = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_nueva_partida = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_capturar_teclas = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_mostrar_pantalla = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_monitor = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


pthread_cond_t cond_carga_movimientos = PTHREAD_COND_INITIALIZER;   // exe en th_f_torneo
pthread_cond_t cond_nueva_partida = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_capturar_teclas = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_mostrar_pantalla = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_monitor = PTHREAD_COND_INITIALIZER;


void sdl_presentacion();
void sdl_esperando_inscripcion(void);
void setear_carga_inicial();
//void carga_inicial();
// optiene las teclas del archivo de configuracion cliente.ini
SDLKey get_tecla(int);
// luego de algun movimiento se refresca la superficie pantalla
void dibujar_fondo(void);
void escribir_nombre_jugador();
void mostrar_pantalla_fin(char *);
void dibujarTextos(void );  //lucas
void fin_juego(char * respuesta);
void pantalla_de_espera();
void pantalla_relanzando_partida();
void muerte_torneo();
void jug_fuera_por_impar();
void verificar_existencia_torneo();


#define WIDTH 640
#define HEIGHT 480
#define BPP 16
#define POS_OCULTAR 1000  // oculta objetos
#define IMAGENES 34     // cant de imagenes

//identificacion de los usuarios dentro de los vectores
#define ID_MARIO 0
#define ID_LUIS 1
#define ID_MONO 2
#define ID_PRINCESA 3
#define ID_VIDA_MARIO_1 4
#define ID_VIDA_MARIO_2 5
#define ID_VIDA_MARIO_3 6
#define ID_VIDA_LUIS_1 7
#define ID_VIDA_LUIS_2 8
#define ID_VIDA_LUIS_3 9
#define ID_BARRIL_0 10
#define ID_FUEGO_0 20
#define ID_PRESENTACION 30
#define ID_FONDO	31
#define ID_FINJUEGO	32
#define ID_ESPERA 33

SDL_Surface *imagenes[IMAGENES];

SDL_Surface *presentacion, *pantalla,*fondo,*esperando, *obj;

SDL_Rect src_pres,dest_pres,src_obj,dest_obj,src_fondo,dest_fondo;
SDL_Rect src_princesa,dest_princesa;
SDL_Rect src_sprites[OBJETOS];

SDL_Color colorfuente;
SDL_Surface *textJug1, * textJug2, * ttextPart;

// inicializo la pantalla oculta
SDL_Surface *pantalla_oculta = SDL_CreateRGBSurface(SDL_SWSURFACE, 640, 480, 16,0,0,0,0);

SDL_Event evento_presentacion;
SDL_Event evento_mario;
SDL_Event evento_princesa;

// para los movimientos de los personajes
struct movimientos {
    int x,y;
};

struct movimientos obj_movi;

// Permite definir que dibujar. th_f_dibujar()
char dibujar[20];

char *buffer2;
int shmid;

// guarda nombre de los jugadores del la funcion escribir_nombre_jugador
char NOM_JUG_1[TAMBUF];
char NOM_JUG_2[TAMBUF];



pthread_t th_torneo; // thread para servidor de torneo
pthread_t th_dibujar;
pthread_t th_capturar_teclas;
pthread_t th_carga_movimientos;
pthread_t th_mostrar_pantalla;
pthread_t th_monitorizar_monitor;


int terminoPartida=0;
int numeroPartida=0;

int rescatesJug1 = 0;
int rescatesJug2= 0;

// para socket
int socket_fd;
char buffer[TAMBUF];


struct sockaddr_in listen_address, con_address;
socklen_t con_addr_len;


typedef struct {
    char tipo_senial[5];
    char identificador[6];
    char senial[5];
    char x[5];
    char y[5];
}envio;


// senial:
// 1.Arriba 2.Izquierda 3.Derecha 4.Abajo 5.Saltar Arriba 6.Saltar Izquierda 7. Saltar Derecha


//queue <envio> cola_recepcion;
//queue <envio> cola_recepcion_copy;



envio recepcion[OBJETOS];
envio recepcion_juego;


// posiciones dentro de recepcion
int vidas_jug1 = ID_VIDA_MARIO_1;
int vidas_jug2 = ID_VIDA_LUIS_1;

int fin_partida = 1;

int shmid_global;

int proceso_torneo = 0; // por defecto no existe el proceso torneo en la misma maquina que el cliente

//int main(int argc, char *argv[]) {



 // Codigo para usar en eclipse
/* -------------------------------------------------------*/

int main() {

	int argc = 2;
	char *argv[2] = { "./cliente", "JERO" };
	if ((chdir("src")) < 0) {
		perror("Cambio de directorio falló...");
	    exit(EXIT_FAILURE);
	}

	char buff[PATH_MAX + 1];
	char*  dir_act = getcwd(buff, sizeof(buff));
	printf("%s\n", dir_act);

/*------------------------------------------------------ */

        //verificar_existencia_torneo();

	ignore_signals();

	// debe ingresar su nombre
	if (argc != 2)
		return ayuda();

	// dibuja la presentacion
	sdl_presentacion();

	//bloqueo todas las señales para que no joda mi recv
	//sigset_t conjsen;
	//sigemptyset(&conjsen);
	//sigfillset(&conjsen);
	//sigprocmask(SIG_SETMASK, &conjsen, NULL);
	//sigfillset(&conjsen);

	// Se anota al torneo
	pthread_create(&th_torneo, NULL, th_f_torneo, (void*) argv[1]);
	pthread_create(&th_carga_movimientos, NULL, th_f_carga_movimientos, NULL);
	pthread_create(&th_mostrar_pantalla, NULL, th_f_mostrar_pantalla, NULL);
	pthread_create(&th_capturar_teclas, NULL, th_f_capturar_teclas, NULL);

        if( proceso_torneo  == 0 )   // el torneo se ejecuta en una maquina distinta
           pthread_create(&th_monitorizar_monitor, NULL, th_f_monitorizar_monitor, NULL);


	// el main espera la finalizacion de todos los thread para poder seguir ejecutando
	pthread_join(th_torneo, NULL);
	pthread_join(th_carga_movimientos, NULL);
	pthread_join(th_capturar_teclas, NULL);
	pthread_join(th_mostrar_pantalla,NULL);
	pthread_join(th_monitorizar_monitor,NULL);


	//atexit(SDL_Quit);

        TTF_Quit();
        SDL_Quit();


	return 0;

}


void  sdl_presentacion() {
	//De esta forma me aseguro que al cerrarse el programa se cierren tambien todos los subsitemas de SDL

	/* incio SDL */
	// inicializar el subsistema SDL, Solo en SDL_INIT_VIDEO
	SDL_inicializar();

	// Inicializamos SDL_ttf
	if (TTF_Init() < 0) {
		printf("No se pudo iniciar SDL_ttf: %s\n", SDL_GetError());
		exit(0);
	}

	//atexit(TTF_Quit);

	/*Inicializo el modo de video con una pantalla de 640 x 480 con 32 bytes de profundidad de color */
	pantalla = SDL_inicializar_modo_video(WIDTH, HEIGHT, BPP);

	setear_carga_inicial();  // setear los valores para carga_inicial

	/* Dibujamos la imagen de presentacion */
	src_pres = SDL_dibujar_imagen_src(imagenes[30], 0, 0);
	dest_pres = SDL_dibujar_imagen_dest(imagenes[30], 0, 0);

	if ((SDL_BlitSurface(imagenes[30], &src_pres, pantalla, &dest_pres)) < 0) {
		cout << "Error SDL_BlitSurface presentacion" << endl;
		exit(1);
	}

	// Actualiza una superficie
	//SDL_Flip(pantalla);

        //plasmar la imagen presentacion en la superficie pantalla
        // superficie,izq,sup,der,inf (0,0,0,0) indica toda la pantalla
	SDL_UpdateRect(pantalla,0,0,0,0);

	// se queda esperando a que se presione ENTER para enviar
	int done = 0;
	while (!done) {
		SDL_WaitEvent(&evento_presentacion); // se queda esperando por algun evento. no consume cpu
//		SDL_PollEvent(&evento_presentacion);  // cola de eventos
			if (evento_presentacion.key.keysym.sym == SDLK_ESCAPE ||  evento_presentacion.type == SDL_QUIT) {
				SDL_FreeSurface(presentacion); // liberar memoria
				SDL_FreeSurface(pantalla);
				exit(0);
			}

		       if (evento_presentacion.type == SDL_KEYDOWN) { // detecta si se presiono una tecla
			   if (evento_presentacion.key.keysym.sym == SDLK_RETURN)
				done = 1;
		}
	}

} // fin sdl_presentacion

void * th_f_torneo(void * nombre_jug) {

	sdl_esperando_inscripcion();
 
       char respuesta[TAMBUF];
       char respuestaFinal[TAMBUF];
       char verMesj[TAMBUF];
       int s,num;


       respuesta[TAMBUF] = '\0';
       memset(&respuesta,'\0',TAMBUF);
       verMesj[TAMBUF] = '\0';
       memset(&verMesj,'\0',TAMBUF);
       respuestaFinal[TAMBUF] = '\0';
       memset(&respuestaFinal,'\0',TAMBUF);

    //   char nom_ganador[TAMBUF];

    // creacion del socket  envia nombre de jugador, se anota al torneo y espera a la respuesta del servidor de torneo
	socket_fd = socket_creacion();

	// conectar con el servidor
	socket_conectar_servidorST(socket_fd);

        cout<<"conexion establecida"<<endl;


    /* -------- MONITOR --------------- */
          // el proceso torneo no existe en esta maquina
    if( proceso_torneo == 0 ){
       ejecutar_monitor();
       sleep(1);  // espera para que el proceso padre no ejecute mas rapido que el hijo (monitor)
       pthread_cond_broadcast(&cond_monitor);
    }
    /* -------------------------------- */




	// Enviamos el mensaje
	send(socket_fd,(char *)nombre_jug, TAMBUF, 0);
	// recibo respuesta: Puedo jugar o no

 	fflush(stdin);
 	fflush(stdout);

	   do{
		     num = recv(socket_fd, (char  *)respuesta, sizeof(respuesta), 0);
	   }while(memcmp("si",respuesta,2)!=0 && memcmp("no",respuesta,2)!=0 && memcmp("torneo",respuesta,6)!=0 && memcmp("mt",respuesta,2)!=0);



	if(num<0)
        {
           
            s = pthread_cancel(th_mostrar_pantalla);
            if(s != 0)
               cout<<"1 pthread_setcancelstate"<<endl;

            s = pthread_cancel(th_capturar_teclas);
            if(s != 0)
               cout<<"2 pthread_setcancelstate"<<endl;

            s = pthread_cancel(th_carga_movimientos);
            if(s != 0)
               cout<<"3 pthread_setcancelstate"<<endl;

            s = pthread_cancel(th_torneo);
            if(s != 0)
               cout<<"4 pthread_setcancelstate"<<endl;

           s = pthread_cancel(th_monitorizar_monitor);
            if(s != 0)
               cout<<"4 pthread_setcancelstate"<<endl;



              close(socket_fd);

              exit(0);
        }
       

        int con,con2;  

       while(1)
       {

           pthread_testcancel();

    	   if (strcmp(respuesta, "si") == 0)
    	   {   // si: Empezar a jugar
    		   // guarda nombre de los dos jugadores   para laboratorio. agregar (void*)NOM_JUG_1
    		   char NOM_JUG_1y2[TAMBUF];

    		   NOM_JUG_1y2[TAMBUF] = '\0';
    	       memset(&NOM_JUG_1y2,'\0',TAMBUF);
       		   NOM_JUG_1[TAMBUF] = '\0';
        	   memset(&NOM_JUG_1,'\0',TAMBUF);
           	   NOM_JUG_2[TAMBUF] = '\0';
               memset(&NOM_JUG_2,'\0',TAMBUF);
               verMesj[TAMBUF] = '\0';
               memset(&verMesj,'\0',TAMBUF);

    		   fin_partida = 1;

               //strcmp(NOM_JUG_1, "");
    		   char * pch;

    		   //strncpy(NOM_JUG_1y2, "",sizeof(NOM_JUG_1y2));
               //bzero(NOM_JUG_1, sizeof(NOM_JUG_1));
      		 	fflush(stdin);
      		 	fflush(stdout);

       		   do{
       		     con = recv(socket_fd, (char *)NOM_JUG_1y2, sizeof(NOM_JUG_1y2), 0);
   	             cout<<"imprimo esto "<<NOM_JUG_1y2<<endl;
       		   }while((con!=26 && con!=0) || memcmp("Ganador: ",NOM_JUG_1y2,7) == 0 || memcmp("si",NOM_JUG_1y2,2) == 0 || memcmp("no",NOM_JUG_1y2,2)==0 || memcmp("torneo",NOM_JUG_1y2,6)==0 || memcmp("mt",NOM_JUG_1y2,2)==0);

			   cout <<"RECV NOM_JUG_1y2: "<<NOM_JUG_1y2<<endl;
			   cout <<"RECV NOM_JUG_1y2 (bytes): "<<con<<endl;

    		   // separo los nombres.
    		   pch = strtok (NOM_JUG_1y2, " ");
    		   strncpy(NOM_JUG_1, pch,sizeof(NOM_JUG_1));
    		   cout <<"RECV NOM_JUG_1: "<<NOM_JUG_1<<endl;

     		   pch = strtok (NULL, " ");
       		   strncpy(NOM_JUG_2, pch,sizeof(NOM_JUG_2));


				//cout <<"RECV NOM_JUG_1y2 (bytes): "<<con<<endl;
				//cout <<"RECV NOM_JUG_1: "<<NOM_JUG_1<<endl;

				//strncpy(NOM_JUG_2, "",sizeof(NOM_JUG_2));
				//bzero(NOM_JUG_2, sizeof(NOM_JUG_2));
				//con = recv(socket_fd, NOM_JUG_2, sizeof(NOM_JUG_2), 0);

				cout <<"RECV NOM_JUG_1y2 (bytes): "<<con<<endl;
				cout <<"RECV NOM_JUG_2: "<<NOM_JUG_2<<endl;

				numeroPartida++;
				terminoPartida=0;

				setear_carga_inicial();
				rescatesJug1 = 0;
				rescatesJug2 = 0;
				escribir_nombre_jugador();

				pthread_cond_broadcast(&cond_carga_movimientos);

				cout<<"1 Esperando por fin de partida (bloqueado hasta recibir la senial de th_carga_movimmientos)"<<endl;

				pthread_cond_wait(&cond_nueva_partida,&mutex_nueva_partida);
				//sleep(2);

				pantalla_de_espera();
			    respuesta[TAMBUF] = '\0';
			    memset(&respuesta,'\0',TAMBUF);
	            verMesj[TAMBUF] = '\0';
	            memset(&verMesj,'\0',TAMBUF);


			 	fflush(stdin);
			 	fflush(stdout);

				do{
	            	printf("RESP PARA CONT \n");
	            	con = recv(socket_fd, (char *)respuesta, sizeof(respuesta), 0);   //USO TAMAÑO 40 SOLO PARA EL GANADOR Y POSICION DEL JUGADOR.
	            	printf("CONTANDO \n");
	                cout<<"2 RECV (bytes) "<<con<<endl;
	                cout<<"imprimo esto "<<respuesta<<endl;
	    		   }while(memcmp("Ganador: ",respuesta,7)!=0 && memcmp("si",respuesta,2)!=0 && memcmp("no",respuesta,2)!=0 && memcmp("torneo",respuesta,6)!=0 && memcmp("mt",respuesta,2)!=0);

            cout<<"2 RECV (bytes) "<<con<<endl;
              // mp = muerte partida mt = muerte torneo
            cout<<"2.1 RECV (GANADOR - Mi Posicion (o SI o mp o mt) ): "<<respuesta<<endl;

          }
         else{ if(strcmp(respuesta,"torneo") == 0 || strcmp(respuesta,"mt") == 0){
               	   cout<<"Fin Servidor Torneo"<<endl;
               	   muerte_torneo();
               	   exit(0);
             	}
         	    else{
         	    	if(strcmp(respuesta,"no") == 0){
         	    		cout<<"respuesta: "<<respuesta<<endl;
         	    		jug_fuera_por_impar();
         	    		exit(0);
         	    	}
         	    	else {

         	    		cout<<"respuesta: "<<respuesta<<endl;
         	    		// separo los nombres.
             		   char * pch2;

             		   pch2 = strtok (respuesta, "*");
             		   strncpy(respuestaFinal, pch2,sizeof(respuestaFinal));
           			   strncat(respuestaFinal,"   Mi Posicion: ",40);
              		   pch2 = strtok (NULL, "*");
                	   strncat(respuestaFinal, pch2,sizeof(respuestaFinal));
             		   cout <<"Respuesta FInal: "<<respuestaFinal<<endl;


         	    		//sleep(2);

//         	    		strcmp(nom_ganador, "");
//         	    		do{
//         	    			fflush(stdin);
//         	    			fflush(stdout);
//         	            	bzero(nom_ganador, TAMBUF);
         	            	//con2 = recv(socket_fd, nom_ganador,TAMBUF, 0);
//        	    		} while ((strcmp(nom_ganador, "fin") == 0 || con2 < 20));


//         	    		cout<<"5 RECV GANADOR (bytes): "<<con2<<endl;
//         	    		cout<<"5.1 Ganador: "<<nom_ganador<<endl;

         	    		cout<<"7 llamada a la funcion fin_juego"<<endl;
         	    		fin_juego((char*)respuestaFinal);//nom_ganador);   // recibo posicion final

         	    		cout<<"8 fin de la funcion fin_juego"<<endl;

         	    		pthread_cancel(th_mostrar_pantalla);
         	    		pthread_cancel(th_carga_movimientos);
         	    		pthread_cancel(th_capturar_teclas);
                                pthread_cancel(th_monitorizar_monitor);

         	    		close(socket_fd);

         	    		exit(0);
         	    	}
         	    }
         }
         cout<<"vuleve al inicio de while(1)"<<endl;

       }  // fin while(1)
}


// luego de presionar ENTER el cliente se queda esperando que el ST lo anote al torneo
void sdl_esperando_inscripcion(void) {

SDL_Color bgcolor, fgcolor;
SDL_Rect rectangulo;
SDL_Surface *ttext;
TTF_Font *fuente;

const char texto[20] = " ";
char msg[20];

// imagen que espera a que el server de torneo lo inscriba
char imagen[128] = "../img/esperando.bmp";
esperando = SDL_cargar_imagen(imagen);

src_pres = SDL_dibujar_imagen_src(esperando, 0, 0);
dest_pres = SDL_dibujar_imagen_dest(esperando, 0, 0);



pthread_mutex_lock(&mutex);

SDL_BlitSurface(esperando, &src_pres, pantalla, &dest_pres);

int f;

f = SDL_Flip(pantalla);
if(f == -1)
  cout<<"error SDl_Flip"<<endl;;


pthread_mutex_unlock(&mutex);




/*
// carga la fuente de letra
fuente = TTF_OpenFont("BRLNSR.ttf", 20);

// inicializa colores para el texto
fgcolor.r = 200;
fgcolor.g = 200;
fgcolor.b = 10;

bgcolor.r = 255;
bgcolor.g = 0;
bgcolor.b = 0;

sprintf(msg, "%s", texto);
ttext = TTF_RenderText_Shaded(fuente, msg, fgcolor, bgcolor);

// posicion del texto esperando ...
rectangulo.y = 440;
rectangulo.x = 300;
rectangulo.w = ttext->w;
rectangulo.h = ttext->h;

// Usamos color rojo para la transparencia del fondo
SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

// Volcamos la superficie a la pantalla
SDL_LockSurface(pantalla);
SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);
SDL_UnlockSurface(pantalla);

// destruimos la fuente de letra
//TTF_CloseFont(fuente);

// liberar superficie
SDL_FreeSurface(ttext);
*/

pthread_mutex_lock(&mutex);

SDL_Flip(pantalla);

pthread_mutex_unlock(&mutex);

SDL_Delay(1000);

}



void* th_f_capturar_teclas(void *) {

//pthread_cond_wait(&cond_capturar_teclas, &mutex_capturar_teclas);



int done = 0;
int enviar; // se el jugador se choca con una pared no le envia la tecla para moverse

// optiene teclas del archivo de configuracion cliente.ini
SDLKey key_up = get_tecla(1);
SDLKey key_left = get_tecla(2);
SDLKey key_right = get_tecla(3);
SDLKey key_down = get_tecla(4);
SDLKey key_saltar = get_tecla(5);

Uint8 *keystates;
envio recepcion_tecla;

// activar repeticion de teclas
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);

while (!done) {


	enviar = 0;

	SDL_WaitEvent(&evento_mario);
	SDL_PollEvent(&evento_mario);

	usleep(15000);

	// tecla salir  SDL_QUIT salir con la cruz de la ventana
	if (evento_mario.key.keysym.sym == SDLK_ESCAPE || evento_mario.type == SDL_QUIT) {

	        sprintf(recepcion_tecla.senial, "%d",0);
		send(socket_fd, &recepcion_tecla, sizeof(recepcion_tecla), 0);

                shmctl(shmid_global,IPC_RMID,(struct shmid_ds *)NULL);  // borrar el segmento compartido

		close(socket_fd);
		//SDL_Quit(); //  cierra todos los subsistemas SDL
		exit(0);

	}



	if (evento_mario.type == SDL_KEYDOWN && fin_partida == 1) { // detecta si se presiono una tecla

		keystates = SDL_GetKeyState( NULL );

		// tecla arriba
		if (evento_mario.key.keysym.sym == key_up) {
		    sprintf(recepcion_tecla.senial, "%d",1);
			//recepcion_tecla.senial = 1;
			enviar = 1;
		}

		// tecla izquierda
		if (evento_mario.key.keysym.sym == key_left) {
			if( keystates[key_saltar])
			    sprintf(recepcion_tecla.senial, "%d",6);
				//recepcion_tecla.senial = 6;
			else
			    sprintf(recepcion_tecla.senial, "%d",2);
				//recepcion_tecla.senial = 2;
			enviar = 1;
		}

		// tecla derecha
		if (evento_mario.key.keysym.sym == key_right) {
			if( keystates[key_saltar])
			    sprintf(recepcion_tecla.senial, "%d",7);
				//recepcion_tecla.senial = 7;
			else
			    sprintf(recepcion_tecla.senial, "%d",3);
				//recepcion_tecla.senial = 3;
			enviar = 1;
		}

		// tecla abajo
		if (evento_mario.key.keysym.sym == key_down) {
		    sprintf(recepcion_tecla.senial, "%d",4);
			//recepcion_tecla.senial = 4;
			enviar = 1;
		}

		// tecla saltar en su misma posicion
		if (evento_mario.key.keysym.sym == key_saltar) {
			if( keystates[key_right])
			    sprintf(recepcion_tecla.senial, "%d",7);
				//recepcion_tecla.senial = 7;
			else
				if( keystates[key_left])
				    sprintf(recepcion_tecla.senial, "%d",6);
					//recepcion_tecla.senial = 6;
				else
				    sprintf(recepcion_tecla.senial, "%d",5);
					//recepcion_tecla.senial = 5;
			enviar = 1;
		}

    // PPP cambiar sock_aceptar por socket_ST solo para pruebas
		if (enviar ) {
			send(socket_fd, &recepcion_tecla, sizeof(recepcion_tecla), 0); // envia la tecla el servidor de partida
		}
	} // fin if
    } // fin while
//return NULL;
}

void dibujar_fondo(void) {

/* Dibujamos la imagen de fondo */
src_fondo = SDL_dibujar_imagen_src(imagenes[31], 0, 0);
dest_fondo = SDL_dibujar_imagen_dest(imagenes[31], 0, 0);

pthread_mutex_lock(&mutex);
SDL_BlitSurface(imagenes[31], &src_fondo, pantalla, &dest_fondo);
pthread_mutex_unlock(&mutex);
}




// Movimiento de los 4 personajes: jug, mono y princesa
void* th_f_carga_movimientos(void *)
{


  int seguir; 
  int aux1_pos;
  int aux2_pos;

  while(1)
  {

   pthread_testcancel();

    //cout<<"Esparando nuevamente th_f_carga_movimientos"<<endl;
    pthread_cond_wait(&cond_carga_movimientos, &mutex_carga_movimientos);

    int seguir = 1;

    char posicion[2]="1";  // alamcena la posicion final del juego

	SDL_FreeSurface(presentacion);
	dibujar_fondo();

     
	escribir_nombre_jugador();

        pthread_mutex_lock(&mutex);

	SDL_Flip(pantalla);

        pthread_mutex_unlock(&mutex);

	int aux_id = 0;
	int int_identification = 0;

	int sprite_inc_x =0;

	//  pthread_cond_broadcast(&cond_capturar_tecla);  // libera el pthread capturar teclas
	int primeraVez = true;
	bzero(&recepcion_juego, sizeof(recepcion_juego));
	int con3;
	int z;

        while((con3=recv(socket_fd, (void*) &recepcion_juego, sizeof(recepcion_juego),0)) > 0 && seguir == 1 ){

        //printf("soy Z %d \n",z);
        for(z=0;z<con3;z+=26){


		if (primeraVez) {  // la primera vez habilita el thread th_f_carga_movimientos que empiece a dibujar
			pthread_cond_broadcast(&cond_mostrar_pantalla);
			primeraVez =  false;
		}


		if(strcmp(recepcion_juego.identificador+z,"fin") == 0)
                {
                     fin_partida = 0;  // deshabilita th_f_capturar_tecla

                     cout<<"Recibi fin"<<endl;
                     seguir = 0;
                     terminoPartida=1;
                     sleep(1);
                     pthread_cond_broadcast(&cond_nueva_partida);

                }



		//logica de proocesamiento de los mensajes entrantes....
		aux_id = 99;
		int_identification = atoi(&(recepcion_juego.identificador[4])+z);
		switch(atoi(recepcion_juego.tipo_senial+z)){
		case 2: //movimiento
			strcpy(recepcion_juego.x,recepcion_juego.x+z);
			//recepcion_juego.x = recepcion_juego.x+z;
			strcpy(recepcion_juego.y,recepcion_juego.y+z);
			//recepcion_juego.y = recepcion_juego.y+z;

		    sprintf(recepcion_juego.x, "%d",(atoi(recepcion_juego.x+z)*10));
			//strcpy(recepcion_juego.x,(char *)(atoi(recepcion_juego.x+z)*10));
			//recepcion_juego.x = (recepcion_juego.x+z)*10;
		    sprintf(recepcion_juego.y, "%d",(atoi(recepcion_juego.y+z)*10));
			//strcpy(recepcion_juego.y,(char *)(atoi(recepcion_juego.y+z)*10));
			//recepcion_juego.y = (recepcion_juego.y+z)*10;

			sprite_inc_x = 0;

			if(strstr(recepcion_juego.identificador+z,"jug_") != NULL)
			{
				aux_id = int_identification - 1;

				if(atoi(recepcion_juego.x) != atoi(recepcion[aux_id].x))
				{
					if(atoi(recepcion_juego.x) > atoi(recepcion[aux_id].x)) //se esta moviendo para la derecha
						sprite_inc_x = 0;
					else
						sprite_inc_x = 40;

					if(src_sprites[aux_id].x == sprite_inc_x)
						src_sprites[aux_id].x = sprite_inc_x + 20;
					else
						src_sprites[aux_id].x = sprite_inc_x;
				}
				else
				{
					if(src_sprites[aux_id].x == 80)
						src_sprites[aux_id].x = 100;
					else
						src_sprites[aux_id].x = 80;
				}

			}
			else if(strstr(recepcion_juego.identificador+z, "fue_") != NULL)
			{
				aux_id = 20 + int_identification;
				if( src_sprites[aux_id].x == 20)
					src_sprites[aux_id].x = 0;
				else
					src_sprites[aux_id].x = 20;
			}
			else if(strstr(recepcion_juego.identificador+z, "mon_") != NULL)
			{
				aux_id = 2;
				if( src_sprites[aux_id].x == 60)
					src_sprites[aux_id].x = 0;
				else
					src_sprites[aux_id].x = 60;
			}
			else if(strstr(recepcion_juego.identificador+z, "pri_") != NULL)
			{
				aux_id = 3;

				if(atoi(recepcion_juego.x) > atoi(recepcion[aux_id].x)) //se esta moviendo para la derecha
					sprite_inc_x = 0;
				else
					sprite_inc_x = 40;


				if(src_sprites[aux_id].x == sprite_inc_x)
					src_sprites[aux_id].x = sprite_inc_x + 20;
				else
					src_sprites[aux_id].x = sprite_inc_x;



			}
			else if(strstr(recepcion_juego.identificador+z, "bar_") != NULL)
			{
				aux_id = 10 + int_identification;
				if(atoi(recepcion_juego.y) != atoi(recepcion[aux_id].y) && atoi(recepcion_juego.x) == atoi(recepcion[aux_id].x))
				{
					if(src_sprites[aux_id].x == 0)
						src_sprites[aux_id].x =  20;
					else
						src_sprites[aux_id].x = 0;
				}
				else
				{
					if(src_sprites[aux_id].x < 40 || src_sprites[aux_id].x == 100)
						src_sprites[aux_id].x =  40;
					else
						src_sprites[aux_id].x += 20;
				}

			}

			///////strcpy(recepcion[aux_id].x,recepcion[aux_id].x+z);
			//recepcion[aux_id].x = recepcion[aux_id].x+z;
			//////strcpy(recepcion[aux_id].y,recepcion[aux_id].y+z);
			//recepcion[aux_id].y = recepcion[aux_id].y+z;

			strcpy(recepcion[aux_id].x,recepcion_juego.x+z);
			//recepcion[aux_id].x = recepcion_juego.x+z;
			strcpy(recepcion[aux_id].y,recepcion_juego.y+z);
			//recepcion[aux_id].y = recepcion_juego.y+z;
			break;

		case 3: //colision
			break;

		case 4: //restar vidas
			//LUCAS: HAY Q CAMBIARLOOOOOOO
			if(strcmp(recepcion_juego.identificador+z,"jug_1") == 0){
				aux_id = vidas_jug1 + atoi(recepcion_juego.x+z) - 1;
                                
			}
			else
			{
				if(strcmp(recepcion_juego.identificador+z,"jug_2") == 0){
					aux_id = vidas_jug2 +atoi(recepcion_juego.x+z) - 1;
				}
			}

			///////strcpy(recepcion[aux_id].x,recepcion[aux_id].x+z);
			//recepcion[aux_id].x = recepcion[aux_id].x+z;
			///////strcpy(recepcion[aux_id].y,recepcion[aux_id].y+z);
			//recepcion[aux_id].y = recepcion[aux_id].y+z;

		    sprintf(recepcion[aux_id].x, "%d",POS_OCULTAR);
			//recepcion[aux_id].x = POS_OCULTAR;
		    sprintf(recepcion[aux_id].y, "%d",POS_OCULTAR);
			//recepcion[aux_id].y = POS_OCULTAR;

			break;

		case 5: // rescate princesa
			if(strcmp(recepcion_juego.identificador+z,"jug_1") == 0)
			{
				rescatesJug1++;
				escribir_nombre_jugador();
			}
			if(strcmp(recepcion_juego.identificador+z,"jug_2") == 0)
			{
				rescatesJug2++;
				escribir_nombre_jugador();
			}

			break;

		case 6: // reiniciar el juego
            terminoPartida=1;
			pantalla_relanzando_partida();
			sleep(2);
			rescatesJug1 = 0;
			rescatesJug2 = 0;
			escribir_nombre_jugador();
			setear_carga_inicial();
			terminoPartida=0;
			pthread_cond_broadcast(&cond_mostrar_pantalla);
			break;
		}
		/*
		if(strcmp(recepcion_juego.identificador+z,"fin") == 0)
                {
                     cout<<"Recibi fin 2"<<endl;
		     pthread_cond_broadcast(&cond_nueva_partida);
                     seguir = 0;
                }
		 */
		bzero(&recepcion_juego, sizeof(recepcion_juego));

        } // fin del for
	}  // fin while

    } // fin while(1)
}


void * th_f_mostrar_pantalla(void*)
{
	pthread_cond_wait(&cond_mostrar_pantalla,&mutex_mostrar_pantalla);

	SDL_Rect dest;
	int k=0;

while(true){

        pthread_testcancel();

	while(!terminoPartida)
	{
		SDL_BlitSurface(imagenes[31], 0, pantalla_oculta, 0);
		dibujarTextos();
		for(k = 0; k < OBJETOS; k++)
		{
			if( !(atoi(recepcion[k].x) == POS_OCULTAR))
			{
				dest.x = atoi(recepcion[k].x);
				dest.y = atoi(recepcion[k].y);
				dest.h = src_sprites[k].h;
				dest.w = src_sprites[k].w;

				SDL_BlitSurface(imagenes[k],&(src_sprites[k]), pantalla_oculta, &dest);
			}
		}
                pthread_mutex_lock(&mutex);

		SDL_BlitSurface(pantalla_oculta,0,pantalla,0);
		SDL_Flip(pantalla);
                pthread_mutex_unlock(&mutex);


	    usleep(30000);
	}
	pthread_cond_wait(&cond_mostrar_pantalla,&mutex_mostrar_pantalla);
}
return NULL;
}

void dibujarTextos()
{
SDL_Rect rectangulo, rectangulo1, rectangulo2;


// posicion del texto ...
rectangulo.x = 245;
rectangulo.y = 402;
rectangulo.w = ttextPart->w;
rectangulo.h = ttextPart->h;


rectangulo1.x = 20;
rectangulo1.y = 15;

rectangulo1.w = textJug1->w;
rectangulo1.h = textJug1->h;

rectangulo2.x = 600 - textJug1->w;
rectangulo2.y = 15;

rectangulo2.w = textJug1->w;
rectangulo2.h = textJug1->h;

	// Volcamos la superficie a la pantalla
	SDL_BlitSurface(textJug1, 0, pantalla_oculta, &rectangulo1);
	SDL_BlitSurface(textJug2, 0, pantalla_oculta, &rectangulo2);
	SDL_BlitSurface(ttextPart, 0, pantalla_oculta, &rectangulo);

}


//// carga todos los personajes
//void carga_inicial() {
//
//	int cant_objetos = 10;
//	int i;
//
//    SDL_Rect dest;
//
//        // carga y muestra los dos jugadores, el mono y la princesa
//	for (i = 0; i < cant_objetos; i++) {
//		dest.
//		SDL_BlitSurface(imagenes[i], 0, pantalla, &dest_obj);
//	} // fin for
//	  // escribe por pantalla el nombre de cada jugador
//    SDL_Flip(pantalla);
//}



void setear_carga_inicial()
{
    // carga todas las imagenes en memoria

    cargarYFormatearImagen(&imagenes[ID_MARIO], "../img/mario_f.bmp");
    src_sprites[ID_MARIO].h = 30;
    src_sprites[ID_MARIO].w = 20;

    sprintf(recepcion[ID_MARIO].x, "%d",20);
    //recepcion[ID_MARIO].x = 20;
    sprintf(recepcion[ID_MARIO].y, "%d",420);
    //recepcion[ID_MARIO].y = 420;
    strcpy(recepcion[ID_MONO].identificador, "jug_1");



    cargarYFormatearImagen(&imagenes[ID_LUIS], "../img/luis_f.bmp");
    src_sprites[ID_LUIS].h 	= 30;
    src_sprites[ID_LUIS].w 	= 20;
    sprintf(recepcion[ID_LUIS].x, "%d",600);
    //recepcion[ID_LUIS].x	= 600;
    sprintf(recepcion[ID_LUIS].y, "%d",420);
    //recepcion[ID_LUIS].y   = 420;
    strcpy(recepcion[ID_MONO].identificador, "jug_2");

    cargarYFormatearImagen(&imagenes[ID_MONO], "../img/mono_f.bmp");
    src_sprites[ID_MONO].h 	= 50;
    src_sprites[ID_MONO].w 	= 60;
    sprintf(recepcion[ID_MONO].x, "%d",POS_OCULTAR);
    //recepcion[ID_MONO].x	= POS_OCULTAR;
    sprintf(recepcion[ID_MONO].y, "%d",POS_OCULTAR);
    //recepcion[ID_MONO].y    = POS_OCULTAR;
    strcpy(recepcion[ID_MONO].identificador, "mon_1");

    cargarYFormatearImagen(&imagenes[ID_PRINCESA], "../img/princesa_f.bmp");
    src_sprites[ID_PRINCESA].h 	= 30;
    src_sprites[ID_PRINCESA].w 	= 20;
    sprintf(recepcion[ID_PRINCESA].x, "%d",POS_OCULTAR);
    //recepcion[ID_PRINCESA].x	= POS_OCULTAR;
    sprintf(recepcion[ID_PRINCESA].y, "%d",POS_OCULTAR);
    //recepcion[ID_PRINCESA].y    = POS_OCULTAR;
    strcpy(recepcion[ID_PRINCESA].identificador, "pri_1");

    cargarYFormatearImagen(&imagenes[ID_VIDA_MARIO_1], "../img/vida_roja.bmp");
    src_sprites[ID_VIDA_MARIO_1].h 	= 20;
    src_sprites[ID_VIDA_MARIO_1].w 	= 20;
    sprintf(recepcion[ID_VIDA_MARIO_1].x, "%d",20);
    //recepcion[ID_VIDA_MARIO_1].x	= 20;
    sprintf(recepcion[ID_VIDA_MARIO_1].y, "%d",60);
    //recepcion[ID_VIDA_MARIO_1].y    = 60;
    strcpy(recepcion[ID_VIDA_MARIO_1].identificador, "vma_1");

    cargarYFormatearImagen(&imagenes[ID_VIDA_MARIO_2], "../img/vida_roja.bmp");
    src_sprites[ID_VIDA_MARIO_2].h 	= 20;
    src_sprites[ID_VIDA_MARIO_2].w 	= 20;
    sprintf(recepcion[ID_VIDA_MARIO_2].x, "%d",50);
    //recepcion[ID_VIDA_MARIO_2].x	= 50;
    sprintf(recepcion[ID_VIDA_MARIO_2].y, "%d",60);
    //recepcion[ID_VIDA_MARIO_2].y    = 60;
    strcpy(recepcion[ID_VIDA_MARIO_2].identificador, "vma_2");

    cargarYFormatearImagen(&imagenes[ID_VIDA_MARIO_3], "../img/vida_roja.bmp");
    src_sprites[ID_VIDA_MARIO_3].h 	= 20;
    src_sprites[ID_VIDA_MARIO_3].w 	= 20;
    sprintf(recepcion[ID_VIDA_MARIO_3].x, "%d",80);
    //recepcion[ID_VIDA_MARIO_3].x	= 80;
    sprintf(recepcion[ID_VIDA_MARIO_3].y, "%d",60);
    //recepcion[ID_VIDA_MARIO_3].y    = 60;
    strcpy(recepcion[ID_VIDA_MARIO_3].identificador, "vma_3");

    cargarYFormatearImagen(&imagenes[ID_VIDA_LUIS_1], "../img/vida_verde.bmp");
	src_sprites[ID_VIDA_LUIS_1].h 	= 20;
	src_sprites[ID_VIDA_LUIS_1].w 	= 20;
    sprintf(recepcion[ID_VIDA_LUIS_1].x, "%d",540);
    //recepcion[ID_VIDA_LUIS_1].x		= 540;
    sprintf(recepcion[ID_VIDA_LUIS_1].y, "%d",60);
    //recepcion[ID_VIDA_LUIS_1].y    	= 60;
    strcpy(recepcion[ID_VIDA_LUIS_1].identificador, "vlu_1");

    cargarYFormatearImagen(&imagenes[ID_VIDA_LUIS_2], "../img/vida_verde.bmp");
    src_sprites[ID_VIDA_LUIS_2].h 	= 20;
    src_sprites[ID_VIDA_LUIS_2].w 	= 20;
    sprintf(recepcion[ID_VIDA_LUIS_2].x, "%d",570);
    //recepcion[ID_VIDA_LUIS_2].x		= 570;
    sprintf(recepcion[ID_VIDA_LUIS_2].y, "%d",60);
    //recepcion[ID_VIDA_LUIS_2].y    	= 60;
    strcpy(recepcion[ID_VIDA_LUIS_2].identificador, "vlu_2");

    cargarYFormatearImagen(&imagenes[ID_VIDA_LUIS_3], "../img/vida_verde.bmp");
    src_sprites[ID_VIDA_LUIS_3].h 	= 20;
    src_sprites[ID_VIDA_LUIS_3].w 	= 20;
    sprintf(recepcion[ID_VIDA_LUIS_3].x, "%d",600);
    //recepcion[ID_VIDA_LUIS_3].x		= 600;
    sprintf(recepcion[ID_VIDA_LUIS_3].y, "%d",60);
    //recepcion[ID_VIDA_LUIS_3].y    	= 60;
    strcpy(recepcion[ID_VIDA_LUIS_3].identificador, "vlu_3");

      // carga barriles
    for(int i=0; i <= 9 ; i++)
    {
       cargarYFormatearImagen(&imagenes[ID_BARRIL_0 + i], "../img/BF_f.bmp");
       src_sprites[ID_BARRIL_0 + i ].h 	= 20;
       src_sprites[ID_BARRIL_0 + i ].w 	= 20;
       sprintf(recepcion[ID_BARRIL_0 + i ].x, "%d",POS_OCULTAR);
       //recepcion[ID_BARRIL_0 + i ].x	= POS_OCULTAR;
       sprintf(recepcion[ID_BARRIL_0 + i ].y, "%d",POS_OCULTAR);
       //recepcion[ID_BARRIL_0 + i ].y    = POS_OCULTAR;
       sprintf(recepcion[ID_BARRIL_0 + i ].identificador, "bar_%d", ID_BARRIL_0 + i );
    }

      // carga fuegos
    for(int i=0;i<=9;i++)
    {
       cargarYFormatearImagen(&imagenes[ID_FUEGO_0 + i], "../img/F_f.bmp");
       src_sprites[ID_FUEGO_0 + i].h 	= 20;
       src_sprites[ID_FUEGO_0 + i].w 	= 20;
       sprintf(recepcion[ID_FUEGO_0 + i ].x, "%d",POS_OCULTAR);
       //recepcion[ID_FUEGO_0 + i ].x		= POS_OCULTAR;
       sprintf(recepcion[ID_FUEGO_0 + i ].y, "%d",POS_OCULTAR);
       //recepcion[ID_FUEGO_0 + i ].y    	= POS_OCULTAR;
       sprintf(recepcion[ID_FUEGO_0 + i ].identificador, "bar_%d", ID_FUEGO_0 + i );
    }

    cargarYFormatearImagen(&imagenes[ID_PRESENTACION], "../img/presentacion.bmp");
    cargarYFormatearImagen(&imagenes[ID_FONDO], "../img/fondo.bmp");
    cargarYFormatearImagen(&imagenes[ID_FINJUEGO], "../img/fin_juego.bmp");
    cargarYFormatearImagen(&imagenes[ID_ESPERA], "../img/fondoVacio.bmp");
}


// ignora todas las seniales
void ignore_signals(void)
{
   signal(SIGHUP,SIG_IGN);
   signal(SIGINT,SIG_IGN);
   signal(SIGQUIT,SIG_IGN);
   signal(SIGTRAP,SIG_IGN);
   signal(SIGABRT,SIG_IGN);
   signal(SIGFPE,SIG_IGN);
   signal(SIGILL,SIG_IGN); 
   signal(SIGUSR1,SIG_IGN); 
   signal(SIGSEGV,SIG_IGN); 
   signal(SIGUSR2,SIG_IGN); 
   signal(SIGPIPE,SIG_IGN); 
   signal(SIGALRM,SIG_IGN); 
   signal(SIGTERM,SIG_IGN); 
   signal(SIGCHLD,SIG_IGN); 
   signal(SIGCONT,SIG_IGN); 
   signal(SIGSTOP,SIG_IGN); 
   signal(SIGTSTP,SIG_IGN); 
   signal(SIGTTIN,SIG_IGN); 
   signal(SIGTTOU,SIG_IGN); 
}



SDLKey get_tecla(int tecla)
{
    char linea[20];
    int cont = 1;
    char *charPointer;

    ifstream f_cliente_ini("../config/cliente.ini");


    while(!f_cliente_ini.eof())
    {
 	
        f_cliente_ini.getline(linea,sizeof(linea));

//      para laboratorio
/*
    	charPointer = strrchr(linea, '\r');
	if(*charPointer) {
		*charPointer = '\0';
	}
*/


        if(tecla == 1)   // tecla arriba
           if(cont == 4){   // posicion donde se encuentra la tecla UP en cliente.ini
              break;
           }  
              
        if(tecla == 2 ) // tecla left
           if(cont == 5){
             break;
           }
 
        if(tecla == 3 ) // tecla derecha
          if(cont == 6){
            break;
          }

       if(tecla == 4) // tecla abajo
          if(cont == 7){
             break;
          }
 
       if(tecla == 5) // tecla saltar           
         if(cont == 8){
           break;
         }

        cont++;
    }

  
    f_cliente_ini.close();


    if(strcmp(linea,"a") == 0)
      return SDLK_a;

    if(strcmp(linea,"b") == 0)
      return SDLK_b;

    if(strcmp(linea,"c") == 0)
      return SDLK_c;

    if(strcmp(linea,"d") == 0)
      return SDLK_d;

    if(strcmp(linea,"e") == 0)
      return SDLK_e;

    if(strcmp(linea,"f") == 0)
      return SDLK_f;

    if(strcmp(linea,"g") == 0)
      return SDLK_g;

    if(strcmp(linea,"h") == 0)
      return SDLK_h;

    if(strcmp(linea,"i") == 0)
      return SDLK_i;

    if(strcmp(linea,"j") == 0)
      return SDLK_j;

    if(strcmp(linea,"k") == 0)
      return SDLK_k;

    if(strcmp(linea,"l") == 0)
      return SDLK_l;

    if(strcmp(linea,"m") == 0)
      return SDLK_m;

    if(strcmp(linea,"n") == 0)
      return SDLK_n;

    if(strcmp(linea,"o") == 0)
      return SDLK_o;

    if(strcmp(linea,"p") == 0)
      return SDLK_p;

    if(strcmp(linea,"q") == 0)
      return SDLK_q;

    if(strcmp(linea,"r") == 0)
      return SDLK_r;

    if(strcmp(linea,"s") == 0)
      return SDLK_s;

    if(strcmp(linea,"t") == 0)
      return SDLK_t;

    if(strcmp(linea,"u") == 0)
      return SDLK_u;

    if(strcmp(linea,"v") == 0)
      return SDLK_v;

    if(strcmp(linea,"w") == 0)
      return SDLK_w;

    if(strcmp(linea,"x") == 0)
      return SDLK_x;

    if(strcmp(linea,"y") == 0)
      return SDLK_y;

    if(strcmp(linea,"z") == 0)
      return SDLK_z;

    if(strcmp(linea,"0") == 0)
      return SDLK_0;

    if(strcmp(linea,"1") == 0)
      return SDLK_1;

    if(strcmp(linea,"2") == 0)
      return SDLK_2;

    if(strcmp(linea,"3") == 0)
      return SDLK_3;

    if(strcmp(linea,"4") == 0)
      return SDLK_4;

    if(strcmp(linea,"5") == 0)
      return SDLK_5;

    if(strcmp(linea,"6") == 0)
      return SDLK_6;

    if(strcmp(linea,"7") == 0)
      return SDLK_7;

    if(strcmp(linea,"8") == 0)
      return SDLK_8;


    if(strcmp(linea,"9") == 0)
      return SDLK_9;


    if(strcmp(linea,"up") == 0)
      return SDLK_UP;


    if(strcmp(linea,"down") == 0)
      return SDLK_DOWN;

    if(strcmp(linea,"left") == 0)
      return SDLK_LEFT;

    if(strcmp(linea,"right") == 0)
      return SDLK_RIGHT;

    if(strcmp(linea,"space") == 0)
      return SDLK_SPACE;

    //si no retorno antes devuelve nada...
    return SDLK_WORLD_95;

}


// por parametro recibo el nombre de los jugadores
void escribir_nombre_jugador()
{
	TTF_Font *fuente;

	char texto[50];
    char numPartida[5];
    SDL_Color bgcolor, fgcolor;


    strcpy(texto,"Partida Nro ");
    sprintf(numPartida, "%d", numeroPartida);
    strcat(texto, numPartida);

     char nombreCompleto1[50];
     char nombreCompleto2[50];

     sprintf(nombreCompleto1,"%s  %d ",NOM_JUG_1,rescatesJug1);
     sprintf(nombreCompleto2,"%d  %s",rescatesJug2, NOM_JUG_2);

     // inicializa colores para el texto
      fgcolor.r = 228;
      fgcolor.g = 166;
      fgcolor.b = 0;

       bgcolor.r = 0;
       bgcolor.g = 0;
       bgcolor.b = 0;

       // LUCAS variable global

	// carga la fuente de letra. Fuente y tamanio
	fuente = TTF_OpenFont("5.ttf", 20);
	//TTF_SetFontStyle(fuente,TTF_STYLE_BOLD);

	colorfuente.r=68;
	colorfuente.g=106;
	colorfuente.b=255;

	 textJug1 = TTF_RenderText_Blended(fuente, nombreCompleto1,  colorfuente);


	textJug2 = TTF_RenderText_Blended(fuente, nombreCompleto2,colorfuente);

    ttextPart = TTF_RenderText_Shaded(fuente, texto, fgcolor, bgcolor);

	SDL_SetColorKey(textJug1, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(textJug1->format, 255, 0, 0));
	SDL_SetColorKey(textJug2, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(textJug2->format, 255, 0, 0));
    // Usamos color rojo para la transparencia del fondo
    SDL_SetColorKey(ttextPart, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttextPart->format, 255, 0, 0));

	dibujarTextos();


	// destruimos la fuente de letra
	//TTF_CloseFont(fuente);

}




// fin de juego
void mostrar_pantalla_fin(char *posicion)
{

       cout<<"funcion mostrar pantalla"<<endl;

	src_fondo = SDL_dibujar_imagen_src(imagenes[32], 0, 0);
	dest_fondo = SDL_dibujar_imagen_dest(imagenes[32], 0, 0);
 
	SDL_BlitSurface(imagenes[32], &src_fondo, pantalla, &dest_fondo);


	SDL_Color bgcolor, fgcolor;
	SDL_Rect rectangulo;
	SDL_Surface *ttext;
	TTF_Font *fuente;

        
	char msg[20]="Posicion: ";

	// carga la fuente de letra. Fuente y tamanio
	fuente = TTF_OpenFont("BRLNSR.ttf", 24);

	// inicializa colores para el texto
	fgcolor.r = 200;
	fgcolor.g = 200;
	fgcolor.b = 10;

	bgcolor.r = 255;
	bgcolor.g = 0;
	bgcolor.b = 0;


        strcat(msg,posicion);

        ttext = TTF_RenderText_Shaded(fuente, msg, fgcolor, bgcolor);

	// posicion del texto esperando ...
              
	rectangulo.x = 300;
	rectangulo.y = 300;

	rectangulo.w = ttext->w;
	rectangulo.h = ttext->h;

	// Usamos color rojo para la transparencia del fondo
	SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

	// Volcamos la superficie a la pantalla
        pthread_mutex_lock(&mutex);
	SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);

	// destruimos la fuente de letra
	//TTF_CloseFont(fuente);

        SDL_Flip(pantalla);

        pthread_mutex_unlock(&mutex);

        SDL_Delay(2000); 

}
void pantalla_relanzando_partida(){
    SDL_Color bgcolor, fgcolor;
    SDL_Rect rectangulo;
    SDL_Surface *ttext;
    TTF_Font *fuente;


    usleep(8500);

    char texto[300];
    strncpy(texto,"    PARTIDA CAIDA. RELANZANDO ... ",300);

     // carga la fuente de letra
     fuente = TTF_OpenFont("SuperMarioBros.ttf", 25);

     // inicializa colores para el texto
      fgcolor.r = 255;
      fgcolor.g = 255;
      fgcolor.b = 255;

       bgcolor.r = 0;
       bgcolor.g = 0;
       bgcolor.b = 0;

       ttext = TTF_RenderText_Shaded(fuente, texto, fgcolor, bgcolor);

       // posicion del texto esperando ...
       rectangulo.y = 220;

       rectangulo.x = 60;
       rectangulo.w = ttext->w;
       rectangulo.h = ttext->h;

       int f;

       // Usamos color rojo para la transparencia del fondo
       SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

       // Volcamos la superficie a la pantalla

       pthread_mutex_lock(&mutex);

       SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);
       f = SDL_Flip(pantalla);

       pthread_mutex_unlock(&mutex);



       if( f == -1 )
        cout<<"Error SDL_Flip"<<endl;

}

void pantalla_de_espera(){
    SDL_Color bgcolor, fgcolor;
    SDL_Rect rectangulo;
    SDL_Surface *ttext;
    TTF_Font *fuente;


    usleep(8500);
    /* Dibujamos la imagen de fondo */
    src_fondo = SDL_dibujar_imagen_src(imagenes[ID_ESPERA], 0, 0);
    dest_fondo = SDL_dibujar_imagen_dest(imagenes[ID_ESPERA], 0, 0);



    pthread_mutex_lock(&mutex);

    SDL_BlitSurface(imagenes[ID_ESPERA], &src_fondo, pantalla, &dest_fondo);
    SDL_Flip(pantalla);

    pthread_mutex_unlock(&mutex);




    cout<<"funcion fin juego"<<endl;
    //cout<<"Mi posicion: "<<posicion<<" Ganador: "<<nom_ganador<<endl;

    char texto[300];
    strncpy(texto," ESPERANDO RESPUESTA DEL TORNEO ... ",300);

     // carga la fuente de letra
     fuente = TTF_OpenFont("SuperMarioBros.ttf", 25);

     // inicializa colores para el texto
      fgcolor.r = 255;
      fgcolor.g = 255;
      fgcolor.b = 255;

       bgcolor.r = 0;
       bgcolor.g = 0;
       bgcolor.b = 0;

       ttext = TTF_RenderText_Shaded(fuente, texto, fgcolor, bgcolor);

       // posicion del texto esperando ...
       rectangulo.y = 220;

       rectangulo.x = 60;
       rectangulo.w = ttext->w;
       rectangulo.h = ttext->h;

       int f;

       // Usamos color rojo para la transparencia del fondo
       SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

       // Volcamos la superficie a la pantalla

       pthread_mutex_lock(&mutex);

       SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);
       f = SDL_Flip(pantalla);

       pthread_mutex_unlock(&mutex);



       if( f == -1 )
        cout<<"Error SDL_Flip"<<endl;


       //SDL_Delay(1000);
       //sleep(2);
}

void fin_juego(char * respuesta ) {

    SDL_Color bgcolor, fgcolor;
    SDL_Rect rectangulo;
    SDL_Surface *ttext;
    TTF_Font *fuente;



    /* Dibujamos la imagen de fondo */
    src_fondo = SDL_dibujar_imagen_src(imagenes[ID_FINJUEGO], 0, 0);
    dest_fondo = SDL_dibujar_imagen_dest(imagenes[ID_FINJUEGO], 0, 0);

    pthread_mutex_lock(&mutex);

    SDL_BlitSurface(imagenes[ID_FINJUEGO], &src_fondo, pantalla, &dest_fondo);
    SDL_Flip(pantalla);


    pthread_mutex_unlock(&mutex);




    cout<<"funcion fin juego"<<endl;
    //cout<<"Mi posicion: "<<posicion<<" Ganador: "<<nom_ganador<<endl;


    char texto[300];

    /* MONITOR 14-12 */
    if(strcmp(respuesta,"mt") == 0)
       strncpy(texto,"Finalizacion por fin de torneo",300);
    else if(strcmp(respuesta,"mp") == 0)
            strncpy(texto,"Finalizacion por fin de partida",300);
         else
             strncpy(texto,respuesta,300);

    /* -------------- */


    cout<<"Texto: "<<texto<<endl;

     // carga la fuente de letra
     fuente = TTF_OpenFont("SuperMarioBros.ttf", 23);

     // inicializa colores para el texto
      fgcolor.r = 255;
      fgcolor.g = 255;
      fgcolor.b = 255;

       bgcolor.r = 0;
       bgcolor.g = 0;
       bgcolor.b = 0;

       ttext = TTF_RenderText_Shaded(fuente, texto, fgcolor, bgcolor);

       // posicion del texto esperando ...
       rectangulo.y = 220;

       rectangulo.x = 60;
       rectangulo.w = ttext->w;
       rectangulo.h = ttext->h;

       // Usamos color rojo para la transparencia del fondo
       SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

       // Volcamos la superficie a la pantalla

       pthread_mutex_lock(&mutex);

       SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);
       SDL_Flip(pantalla);

       pthread_mutex_unlock(&mutex);

       SDL_Delay(10000);
       sleep(10);

}

void jug_fuera_por_impar(void){

    SDL_Color bgcolor, fgcolor;
    SDL_Rect rectangulo;
    SDL_Surface *ttext;
    TTF_Font *fuente;



    cout<<"fuera por impar"<<endl;
    /* Dibujamos la imagen de fondo */
    src_fondo = SDL_dibujar_imagen_src(imagenes[ID_FINJUEGO], 0, 0);
    dest_fondo = SDL_dibujar_imagen_dest(imagenes[ID_FINJUEGO], 0, 0);

    SDL_BlitSurface(imagenes[ID_FINJUEGO], &src_fondo, pantalla, &dest_fondo);




    char texto[50];
    strcpy(texto,"No se pudo armar partida");



     // carga la fuente de letra
     fuente = TTF_OpenFont("5.ttf", 30);

     // inicializa colores para el texto
      fgcolor.r = 200;
      fgcolor.g = 200;
      fgcolor.b = 10;

       bgcolor.r = 255;
       bgcolor.g = 0;
       bgcolor.b = 0;

	ttext = TTF_RenderText_Shaded(fuente, texto, fgcolor, bgcolor);

       // posicion del texto esperando ...
       rectangulo.y = 220;

       rectangulo.x = 60;
        rectangulo.w = ttext->w;
        rectangulo.h = ttext->h;

       // Usamos color rojo para la transparencia del fondo
       SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

       // Volcamos la superficie a la pantalla
       pthread_mutex_lock(&mutex);

       SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);
       SDL_Flip(pantalla);

       pthread_mutex_unlock(&mutex);


       SDL_Delay(10000);


}


void muerte_torneo(void)
{

    SDL_Color bgcolor, fgcolor;
    SDL_Rect rectangulo;
    SDL_Surface *ttext;
    TTF_Font *fuente;



    cout<<"muerte de torneo"<<endl;

    /* Dibujamos la imagen de fondo */
    src_fondo = SDL_dibujar_imagen_src(imagenes[ID_FINJUEGO], 0, 0);
    dest_fondo = SDL_dibujar_imagen_dest(imagenes[ID_FINJUEGO], 0, 0);

    SDL_BlitSurface(imagenes[ID_FINJUEGO], &src_fondo, pantalla, &dest_fondo);



    char texto[50];
    strcpy(texto,"El torneo dejo de existir");



     // carga la fuente de letra
     fuente = TTF_OpenFont("5.ttf", 30);

     // inicializa colores para el texto
      fgcolor.r = 200;
      fgcolor.g = 200;
      fgcolor.b = 10;

       bgcolor.r = 255;
       bgcolor.g = 0;
       bgcolor.b = 0;

        ttext = TTF_RenderText_Shaded(fuente, texto, fgcolor, bgcolor);

       // posicion del texto esperando ...
       rectangulo.y = 220;

      rectangulo.x = 60;
        rectangulo.w = ttext->w;
        rectangulo.h = ttext->h;

       // Usamos color rojo para la transparencia del fondo
       SDL_SetColorKey(ttext, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ttext->format, 255, 0, 0));

       // Volcamos la superficie a la pantalla
       pthread_mutex_lock(&mutex);

       SDL_BlitSurface(ttext, NULL, pantalla, &rectangulo);
       SDL_Flip(pantalla);

       pthread_mutex_unlock(&mutex);

       SDL_Delay(10000);

}


/* --------- MONITOR ---------- */

void ejecutar_monitor(void)
{


      /* ---- Share Memory ---- */
      char linea[30];
      char c_socket[30];
      char c_shmid[30];

      shmid = shmget(SHMKEY,sizeof(linea),0666|IPC_CREAT);
      buffer2 = (char *)shmat(shmid,(char*)0,0);

      pid_t pid = fork();

       if( pid == 0 )  // proceso monitor
       {

    	   buffer2[sizeof(buffer2)]='\0';
           sprintf(buffer2,"%d",getpid());  // almacena el pid en la shm
           sprintf(c_socket,"%d",socket_fd);
           sprintf(c_shmid,"%d",shmid);
           printf("MEMORIA COMPARTIDA %d",shmid);

           execlp(PATH_MONITOR,"MonitorClient",c_socket,c_shmid,NULL);
           //execlp("../../MonitorClient/monitor.bin","monitor.bin",c_socket,c_shmid,NULL);

       }


}



void * th_f_monitorizar_monitor(void *)
{

     pthread_testcancel();

     pthread_cond_wait(&cond_monitor,&mutex_monitor);


      /* crecion de la memoria compartida */
      int pidMonitor;
      //int shmid;
      //char *buffer;
      //char linea[30];

      //shmid = shmget(SHMKEY,sizeof(linea),0666 | IPC_CREAT);

      shmid_global = shmid;

      //buffer = (char *)shmat(shmid,(char*)0,0);

      //buffer[sizeof(buffer)]='\0';


    while(1)
    {


      usleep(1000000*2);  // 1 seg

      pidMonitor = atoi(buffer2);

       if( kill(pidMonitor,0) == -1 )
       {
 //        cout<<"EL MONITOR HA DEJADO DE EJECUTAR"<<endl;
         reEjecutar_monitor();

       }
       printf("Monitor Cliente %d \n",pidMonitor);
       cout<<"El monitor esta ejecutando"<<endl;

   } // fin while


}


void reEjecutar_monitor(void)
{


      /* ---- Share Memory ---- */
      char c_socket[30];
      char c_shmid[30];

      pid_t pid = fork();

       if( pid == 0 )  // proceso monitor
       {

    	   buffer2[sizeof(buffer2)]='\0';
           sprintf(buffer2,"%d",getpid());  // almacena el pid en la shm
           sprintf(c_socket,"%d",socket_fd);
           sprintf(c_shmid,"%d",shmid);
           //printf("MEMORIA COMPARTIDA %d",shmid);

           execlp(PATH_MONITOR,"MonitorClient",c_socket,c_shmid,NULL);
           //execlp("../../MonitorClient/monitor.bin","monitor.bin",c_socket,c_shmid,NULL);

       }


}


/* Si el torneo existe en la misma maquina que el cliente, entonces no lanzo el monitor del cliente */

void verificar_existencia_torneo()
{

         char procesoTorneo[100]="ps ax | grep ServerTournament | grep -v grep | cut -d' ' -f2";

         FILE *r_procesoTorneo = popen(procesoTorneo,"r");
         char pid_buffer[30] = "xxx";
         fscanf(r_procesoTorneo,"%100s",pid_buffer);
         pclose(r_procesoTorneo);

        if(strcmp(pid_buffer,"xxx") != 0)
           proceso_torneo = 1;

}
